home *** CD-ROM | disk | FTP | other *** search
/ Plug-In Power Pack for Netscape Communicator / Plug-In Power Pack for Netscape Communicator.iso / plugins / dataviews / dvtools / examples / programs / pixreps.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-08  |  17.2 KB  |  560 lines

  1. #ifndef    lint
  2. static char SccsId[]= "@(#)pixreps.c    V1.11    3/13/95";
  3. #endif
  4. /*
  5. |    file name - pixreps.c
  6. |===================================================================
  7. |
  8. |    This program demonstrates the use of pixreps. It allows the user
  9. |    to create a pixrep whose red, green and blue components are taken
  10. |    from any combination of three other pixreps.
  11. |
  12. |    The image used in this example program is found in the
  13. |    <dataviews>/lib/images directory.
  14. |
  15. |    The programs ends if the user selects the <q|Q> key or the
  16. |    right mouse button.
  17. |
  18. |===================================================================
  19. */
  20. #include <windows.h>
  21.  
  22. /*
  23.  *  DV-Tools header files
  24.  */
  25. #include "std.h"           /* <stdio.h> etc., scalar & macro definitions */
  26. #include "dvstd.h"         /* public types & constants */
  27. #include "dvtools.h"       /* constants used by T routines */
  28. #include "dvGR.h"          /* constants used by window mgt & GR routines */
  29. #include "VOstd.h"         /* constants used by VO & VOob routines */
  30. #include "Tfundecl.h"      /* T routines (screens, drawports & views) */
  31. #include "VOfundecl.h"     /* VO routines (objects) */
  32. #include "VUerfundecl.h"   /* VUer routines (event handling routines) */
  33. #include "VUpixrep.h"      /* Contains the pixscan macros */
  34. #include "VGfundecl.h"     /* VG routines (get info from dgp & vdp) */
  35. #include "VUfundecl.h"     /* VU routines (Utility) */
  36. #include "GRfundecl.h"     /* GR routines (interface to display device) */    
  37.  
  38. /* Constants */
  39. #define  DVPATH            (char *)NULL
  40. #define  DISPFORMS_STB     (char *)NULL
  41. #define  DVDEVICE          (char *)NULL
  42. #define  DVCOLORTABLE      (char *)NULL
  43. #define  VIEW_NAME         "pixreps.v"
  44. #define  SCREEN_VIEWPORT   (RECTANGLE *)NULL
  45. #define  DRAWING_VIEWPORT  (RECTANGLE *)NULL
  46.  
  47.  
  48. /* height and width of the pixreps */
  49. #define PIXWIDTH   128
  50. #define PIXHEIGHT  128
  51.  
  52. PIXREP pixrep[4];               /* initial pixreps */
  53. PIXREP mergedpixrep;            /* merged pixreps */
  54.  
  55. COLOR_TABLE GreyClut;           /* Greyscale color table */
  56. COLOR_TABLE *DeviceClut;        /* current device clut */
  57.  
  58. /* which pixreps provide which component */
  59. UBYTE RedBuf   = 1;
  60. UBYTE GreenBuf = 2;
  61. UBYTE BlueBuf  = 3;
  62. UBYTE LastRed, LastGreen, LastBlue;
  63.  
  64. DRAWPORT drawport;
  65. OBJECT drawing, icon[5];
  66.  
  67. /* Functions defined in pixreps.c */
  68. LOCAL  void CreatePixrep1 V_P_((void));
  69. LOCAL  void CreatePixrep2 V_P_((void));
  70. LOCAL  void CreatePixrep3 V_P_((void));
  71. LOCAL  void CreateMergedPixrep V_P_((void));
  72. LOCAL  void MergePixreps V_P_((void));
  73. LOCAL  ADDRESS RebindVdps V_P_((OBJECT data_obj, ADDRESS vdp,
  74.                 ADDRESS argblock));
  75.  
  76. /***************** End Function Declarations *************/
  77. int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
  78.                      LPSTR lpCmdLine,  int nCmdShow  )
  79. {
  80.   /*
  81.    *  program arguments
  82.    *    argv[1] - display device name (default is to use DVDEVICE)
  83.    */
  84.  
  85.   /* Define & initialize device name and view filename */
  86.   char *device_name = DVDEVICE; /* default device name */
  87.   char *view_name = VIEW_NAME;  /* default view name */
  88.  
  89.   OBJECT screen, location;
  90.   VIEW view;
  91.   OBJECT pixmap;
  92.   int Quit = NO, i;
  93.  
  94.   int argc;
  95.   char **argv;
  96.  
  97.  
  98.   make_argv(&argc,&argv,GetCommandLine());
  99.   /*--------------------
  100.    *   Initialization
  101.    *
  102.    *   TInit:  perform the initialization of DV-Tools
  103.    *           TInit reads your configuration file and any
  104.    *           environment variables or logical names set.
  105.    */
  106.   TInit (DVPATH, DISPFORMS_STB);
  107.  
  108.   /*
  109.    *   TscOpenSet: open a device as a screen object using
  110.    *               specified attributes
  111.    *   TscErase:   erase the entire screen in the default
  112.    *               background color
  113.    *
  114.    *   Set exposure block to YES to insure the window
  115.    *   is ready for drawing when TdpDraw is called.
  116.    */
  117.   if (argc > 1)
  118.     device_name = argv[1];
  119.   screen = TscOpenSet (device_name, DVCOLORTABLE,
  120.                        V_WINDOW_WIDTH, 840,
  121.                        V_WINDOW_HEIGHT, 644,
  122.                        V_X_EXPOSURE_BLOCK, YES,
  123.                        V_ACTIVE_CURSOR, V_END_OF_LIST);
  124.   if (!screen)
  125.     {
  126.       printf ("Must specify device on command line or");
  127.       printf (" in DataViews configuration file.\n");
  128.       S_EXIT (EXIT_ERR);
  129.     }
  130.   TscErase (screen);
  131.  
  132.   /* Set the window events that we need to know about */
  133.   VOscWinEventMask ((ULONG) V_KEYPRESS | V_BUTTONPRESS | V_MOTIONNOTIFY |
  134.                 V_RESIZE | V_EXPOSE,
  135.             (ULONG) 0);
  136.   view = TviLoad (view_name);
  137.   drawport = TdpCreateStretch (screen, view, SCREEN_VIEWPORT,
  138.                                DRAWING_VIEWPORT);
  139.  
  140.   /*
  141.    *  Traverse all variable descriptors in the drawing object
  142.    *  call the function RebindVdps for each variable descriptor.
  143.    */
  144.   drawing = TviGetDrawing (view);
  145.   TobForEachVdp (drawing, (TOBFOREACHVDPFUNPTR)RebindVdps, (ADDRESS) NULL);
  146.  
  147.   icon[1] = VOicReference (TdrGetNamedObject (drawing, "icon1"));
  148.   VOdrObDelete (drawing, icon[1]);
  149.   icon[2] = VOicReference (TdrGetNamedObject (drawing, "icon2"));
  150.   VOdrObDelete (drawing, icon[2]);
  151.   icon[3] = VOicReference (TdrGetNamedObject (drawing, "icon3"));
  152.   VOdrObDelete (drawing, icon[3]);
  153.   icon[4] = VOicReference (TdrGetNamedObject (drawing, "mergedicon"));
  154.   VOdrObDelete (drawing, icon[4]);
  155.  
  156.   /* =========================================================== */
  157.   /* Create pixreps, create pixmap objects from pixreps, and     */
  158.   /* replace icon's initial pixmaps with the new pixmaps.        */
  159.   /* =========================================================== */
  160.  
  161.   /* create a greyscale color table for use by pixreps. */
  162.   for (i = 0; i < 256; i++)
  163.     {
  164.       GreyClut.ct[i].red = i;
  165.       GreyClut.ct[i].green = i;
  166.       GreyClut.ct[i].blue = i;
  167.     }
  168.   GreyClut.ctsize = 256;
  169.  
  170.   /* find actual colors displayed on the screen */
  171.   GRg_real_color_tab (&DeviceClut);
  172.  
  173.   CreatePixrep1 ();
  174.   CreatePixrep2 ();
  175.   CreatePixrep3 ();
  176.  
  177.   /* ========================= */
  178.   /* start displaying the view */
  179.   /* ========================= */
  180.   TdpDraw (drawport);
  181.  
  182.   CreateMergedPixrep ();
  183.  
  184.   pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrep[1]);
  185.   /* Dither pixmap so it displays better given the limited number
  186.    | of greys in the default color table.
  187.    */
  188.   VOpmNewColorTable (pixmap, DeviceClut, YES);
  189.   VOicSet (icon[1], V_IC_PIXMAP, pixmap,
  190.            V_IC_WIDTH, PIXWIDTH,
  191.            V_IC_HEIGHT, PIXHEIGHT,
  192.            V_IC_PIXMAP_XFORM, NULL,
  193.            V_IC_ATTR_ARGEND);
  194.  
  195.   pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrep[2]);
  196.   VOpmNewColorTable (pixmap, DeviceClut, YES);
  197.   VOicSet (icon[2], V_IC_PIXMAP, pixmap,
  198.            V_IC_WIDTH, PIXWIDTH,
  199.            V_IC_HEIGHT, PIXHEIGHT,
  200.            V_IC_PIXMAP_XFORM, NULL,
  201.            V_IC_ATTR_ARGEND);
  202.  
  203.   pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrep[3]);
  204.   VOpmNewColorTable (pixmap, DeviceClut, YES);
  205.   VOicSet (icon[3], V_IC_PIXMAP, pixmap,
  206.            V_IC_WIDTH, PIXWIDTH,
  207.            V_IC_HEIGHT, PIXHEIGHT,
  208.            V_IC_PIXMAP_XFORM, NULL,
  209.            V_IC_ATTR_ARGEND);
  210.  
  211.   for (i = 1; i < 4; i++)
  212.     TdpDrawObject (drawport, icon[i]);
  213.  
  214.   FOREVER
  215.   {
  216.  
  217.     /* Get the latest event */
  218.     location = VOloWinEventPoll (V_WAIT);
  219.     switch (VOloType (location))
  220.       {
  221.  
  222.       case V_EXPOSE:
  223.         TscRedraw (screen, (RECTANGLE *) NULL);
  224.         for (i = 1; i <= 4; i++)
  225.           TdpRedrawObject (drawport, icon[i]);
  226.         break;
  227.  
  228.       case V_RESIZE:
  229.         TscReset (screen);
  230.         break;
  231.  
  232.       case V_KEYPRESS:
  233.         switch (VOloKeySym (location))
  234.           {
  235.           case 'q':
  236.           case 'Q':
  237.             Quit = YES;
  238.             break;
  239.  
  240.           default:
  241.             break;
  242.           }
  243.         break;
  244.  
  245.       case V_BUTTONPRESS:
  246.       case V_MOTIONNOTIFY:
  247.         /*
  248.          * Call the event handler so input objects respond to
  249.          * user interactions.
  250.          */
  251.         VUerHandleLocEvent (location);
  252.  
  253.         /* if the color values have changed since last time,
  254.      * modify the merged pixrep.
  255.      */
  256.         if (LastRed != RedBuf || LastBlue != BlueBuf ||
  257.         LastGreen != GreenBuf)
  258.           MergePixreps ();
  259.  
  260.         /*
  261.          *   Update the dynamic parts of the current drawport by
  262.          *     redrawing the dynamic elements that have changed.
  263.          */
  264.         TdpDrawNext (drawport);
  265.         break;
  266.  
  267.       default:
  268.         break;
  269.       }
  270.     if (Quit == YES)
  271.       break;
  272.   }
  273.  
  274.   /*
  275.    *    When finished, destroy the current drawport and view
  276.    *    close the graphics device and terminate DV-Tools.
  277.    */
  278.   TscErase (screen);
  279.   TdpDestroy (drawport);
  280.   TviDestroy (view);
  281.   TscCloseCurrentScreen ();
  282.   TTerminate ();
  283.   return (EXIT_OK);
  284. }
  285.  
  286. /*
  287.  * CreatePixrep1()
  288.  * This illustrates creating a pixrep "from scratch", such as might be
  289.  * done if you want to convert data from an external source into
  290.  * a pixrep.
  291.  * Pixrep 1 starts out white on the left edge and fades to
  292.  * black towards the right edge.
  293.  */
  294. LOCAL void CreatePixrep1 ()
  295. {
  296. #ifndef USE_PIXSCAN_MACROS
  297.   int i;
  298. #else
  299.   PIXSCAN pixscan;
  300.   PIXPTR pixptr;
  301.   ULONG pixval;
  302. #endif
  303.  
  304.   int x, y;
  305.   UBYTE *pixel_data;
  306.  
  307.   /*
  308.    * Initialize a pixrep. In this program there is no real reason to prefer
  309.    * one layout over another, but for illustration we'll create one
  310.    * with a specific format:
  311.    * 8 bits per pixel of indirect color, the bottom row of the pixrep
  312.    * will be row 0 (i.e. comes first in the data array) and rows
  313.    * are contiguous in memory (no padding between rows).
  314.    */
  315.   pixrep[1].height = PIXHEIGHT;
  316.   pixrep[1].width = PIXWIDTH;
  317.   pixrep[1].origin_at_ll = YES; /* row[0] is bottom row */
  318.   pixrep[1].row_alignment = 8;  /* rows contiguous */
  319.   pixrep[1].pack_unit = 8;      /* only matters if bits/pixel < 8 */
  320.   pixrep[1].pack_msf_in_byte = NO;      /* only matters if bits/pixel < 8 */
  321.   pixrep[1].pack_msf_in_unit = YES;     /* only matters if bits/pixel < 8 */
  322.   pixrep[1].depth = 8;
  323.   pixrep[1].bits_per_pixel = 8;
  324.   pixrep[1].pclut = (COLOR_TABLE *) S_ALLOC ((LONG) sizeof (COLOR_TABLE));
  325.   *pixrep[1].pclut = GreyClut;
  326.   pixrep[1].color_used = NULL;  /* all colors will be used anyway */
  327.   pixrep[1].pixels_length = PIXHEIGHT * VUpxBytesPerRow (&pixrep[1]);
  328.   pixel_data = (UBYTE *) S_ALLOC ((LONG) pixrep[1].pixels_length);
  329.   pixrep[1].pixels = pixel_data;
  330.  
  331. #ifndef USE_PIXSCAN_MACROS
  332.  
  333.   /*
  334.    * There are two ways to initialize the data. One way is to modify
  335.    * the pixel data directly. (The data may also come from some
  336.    * other source (such as an X XImage structure) and be used without
  337.    * modification by setting the appropriate pixrep fields.)
  338.    */
  339.   i = 0;
  340.   for (y = 0; y < PIXHEIGHT; y++)
  341.     for (x = 0; x < PIXWIDTH; x++)
  342.       pixel_data[i++] = 255 - (2 * x);
  343.  
  344. #else
  345.  
  346.    /*
  347.     * Or the data can be modified using the pixscan macros
  348.     * The following is an example of initializing the data using the
  349.     * pixscan macros.
  350.     */
  351.    VUpxScanInit (&pixrep[1], &pixscan, &pixptr, YES);
  352.   
  353.    for (y = 0; y < PIXHEIGHT; y++)
  354.       for (x = 0; x < PIXWIDTH; x++)
  355.         {
  356.           pixval = 255 - (2 * x);
  357.           PXSCANWRITE (pixrep[1], pixscan, pixptr, pixval);
  358.         }
  359. #endif
  360. }
  361.  
  362. /*
  363.  * CreatePixrep2()
  364.  * This illustrates creating a pixrep from a pixmap object.
  365.  * It also shows how some of the pixrep utilities work as well
  366.  * as how to use some of the pixscan macros.
  367.  * Pixrep 2 is part of a greyscale version of rose.gif.
  368.  */
  369. LOCAL void CreatePixrep2 ()
  370. {
  371.   OBJECT pixmap;
  372.   PIXREP *pixrepp;
  373.   PIXREP tpixrep;
  374.   RECTANGLE rect;
  375.   PIXSCAN pixscan1, pixscan2;
  376.   PIXPTR pixptr1, pixptr2;
  377.   ULONG pixval;
  378.   int i;
  379.  
  380.  
  381.   pixmap = VOpmCreate ("rose.gif", (ADDRESS)NULL);
  382.  
  383.   if (!pixmap)                  /* failed, create a boring pixrep. */
  384.     VUpxRotate (&pixrep[2], &pixrep[1], 180);
  385.   else
  386.     {
  387.       VOpmGet (pixmap, V_PM_PIXREP_DATA, &pixrepp, V_PM_ATTR_ARGEND);
  388.  
  389.       /* clip out a 128x128 square from the pixrep (makes a COPY!) */
  390.       rect.ll.x = 60;
  391.       rect.ll.y = 50;
  392.       rect.ur.x = rect.ll.x + PIXWIDTH - 1;
  393.       rect.ur.y = rect.ll.y + PIXHEIGHT - 1;
  394.       VUpxClip (&tpixrep, pixrepp, &rect);
  395.  
  396.       /* convert to greyscale (another copy) */
  397.       VUpxNewColorTable (&pixrep[2], &tpixrep, &GreyClut, NO);
  398.  
  399.       /*
  400.        * The rose is a bit dark, so brighten it a bit by increasing
  401.        * each pixel's intensity by a few levels.
  402.        * Create two pixscans, one to read a pixel from the pixrep
  403.        * and one to write it back.
  404.        */
  405.       VUpxScanInit (&pixrep[2], &pixscan1, &pixptr1, YES);
  406.       VUpxScanInit (&pixrep[2], &pixscan2, &pixptr2, YES);
  407.       for (i = pixrep[2].width * pixrep[2].height; i > 0; i--)
  408.         {
  409.           PXSCANREAD (pixval, pixrep[2], pixscan1, pixptr1);
  410.           pixval = S_MIN (pixval + 50, 255);
  411.           PXSCANWRITE (pixrep[2], pixscan2, pixptr2, pixval);
  412.         }
  413.  
  414.       /* cleanup */
  415.       VOpmDereference (pixmap);
  416.       VUpxFree (&tpixrep);
  417.     }
  418.  
  419. }
  420.  
  421. /*
  422.  * CreatePixrep3()
  423.  * This illustrates another pixrep utility.
  424.  * Pixrep 3 is simply a rotated version of pixrep 1.
  425.  */
  426. LOCAL void CreatePixrep3 ()
  427. {
  428.   VUpxRotate (&pixrep[3], &pixrep[1], 90);
  429. }
  430.  
  431. /*
  432.  * CreateMergedPixrep()
  433.  * Create the pixrep that will hold the merged color information.
  434.  */
  435. LOCAL void CreateMergedPixrep ()
  436. {
  437.  
  438.   /* Initialize the pixrep structure. The only things we care about
  439.    * are the height, width and that it have 24 bits of direct color
  440.    * information.
  441.    */
  442.   VUpxDefault (&mergedpixrep, PIXHEIGHT, PIXWIDTH, (COLOR_TABLE *) NULL,
  443.                (ULONG) 0xFF, (ULONG) 0xFF00, (ULONG) 0xFF0000);
  444.   mergedpixrep.pixels = (UBYTE *) S_ALLOC ((LONG) mergedpixrep.pixels_length);
  445.  
  446.   /* merge the initial pixreps together and put result in mergedpixrep */
  447.   MergePixreps ();
  448. }
  449.  
  450. /*
  451.  * MergePixreps()
  452.  * The color information for the merged pixrep comes from various
  453.  * combinations of the three initial pixreps. This function merges
  454.  * the chosen combination together and displays the result.
  455.  */
  456. LOCAL void MergePixreps ()
  457. {
  458.   OBJECT pixmap;
  459.   PIXREP pixrepdraw;
  460.  
  461.   /* Erase existing icon while we're working */
  462.   TdpEraseObject (drawport, icon[4]);
  463.  
  464.   /*
  465.    * Combine the color components together. Modifies mergedpixrep, does
  466.    * not create copy.
  467.    *
  468.    * Each pixrep contributes its red, green, or blue component to the
  469.    * result. Since all three pixreps have a greyscale color table, each
  470.    * color value in this table has equal components of red, green and
  471.    * blue. This means that any of the three pixreps can be used for any
  472.    * component.
  473.    *
  474.    * Suppose you wanted a pixrep's pixel values to be interpreted as the
  475.    * green component for a new pixrep, but its color table consisted only of
  476.    * levels of red. Simply change its "pclut" field (temporarily at least)
  477.    * to point to a color table consisting of levels of green and continue
  478.    * as below.
  479.    */
  480.  
  481.   VUpxChannelMerge (&mergedpixrep, &pixrep[RedBuf], &pixrep[GreenBuf],
  482.                     &pixrep[BlueBuf]);
  483.  
  484.   /*
  485.    * The result uses 24 bits of direct color. To get it to display nicely
  486.    * on the current device, we create a copy of the pixrep that uses
  487.    * the current device color table.
  488.    * Dither the resulting pixrep so it looks better.
  489.    */
  490.   VUpxNewColorTable (&pixrepdraw, &mergedpixrep, DeviceClut, YES);
  491.  
  492.   /*
  493.    * Turn pixrep into pixmap object and replace merged icon's current
  494.    * pixmap with the new one.
  495.    */
  496.   pixmap = VOpmCreate ((char *)NULL, (ADDRESS) & pixrepdraw);
  497.   VOicSet (icon[4], V_IC_PIXMAP, pixmap,
  498.            V_IC_WIDTH, PIXWIDTH,
  499.            V_IC_HEIGHT, PIXHEIGHT,
  500.            V_IC_PIXMAP_XFORM, NULL,
  501.            V_IC_ATTR_ARGEND);
  502.  
  503.   /* refresh the screen image of icon */
  504.   TdpDrawObject (drawport, icon[4]);
  505.  
  506.   VUpxFree (&pixrepdraw);
  507.  
  508.   /* remember the colors just chosen */
  509.   LastRed = RedBuf;
  510.   LastGreen = GreenBuf;
  511.   LastBlue = BlueBuf;
  512.  
  513. }
  514.  
  515. /*
  516.  *-------------
  517.  *   RebindVdps -- modify the variable descriptor to use
  518.  *     our own program variable as the memory buffer.
  519.  *     The variable descriptor which had previously
  520.  *     pointed to a data source variable for the data
  521.  *     will now look at our program variable for the
  522.  *     data information.
  523.  */
  524. /*ARGSUSED*/
  525. LOCAL ADDRESS 
  526. RebindVdps (data_obj, vdp, argblock)
  527.      OBJECT data_obj;
  528.      ADDRESS vdp;
  529.      ADDRESS argblock;
  530. {
  531.   char *name;                   /* variable descriptor name */
  532.  
  533.   /*
  534.    *   VGvdvarname:  Gets a pointer to the variable name
  535.    *
  536.    *   The name of the variable descriptor is used to
  537.    *   determine which buffer to rebind to.  If the
  538.    *   variable does not have a name then return.
  539.    */
  540.   name = VGvdvarname (vdp);
  541.   if (!name)
  542.     return V_CONTINUE_TRAVERSAL;
  543.  
  544.   /*
  545.    *   TvdPutBuffer:  Sets a new variable descriptor buffer
  546.    *
  547.    *   Rebind variable descriptor pointer to internal program
  548.    *   variable.  Program variable will be updated for
  549.    *   dynamic objects.
  550.    */
  551.   if (strcmp (name, "red") == 0)
  552.     TvdPutBuffer (vdp, (ADDRESS) & RedBuf);
  553.   else if (strcmp (name, "green") == 0)
  554.     TvdPutBuffer (vdp, (ADDRESS) & GreenBuf);
  555.   else if (strcmp (name, "blue") == 0)
  556.     TvdPutBuffer (vdp, (ADDRESS) & BlueBuf);
  557.  
  558.   return V_CONTINUE_TRAVERSAL;
  559. }
  560.